import * as d3 from 'd3';

// const range = (num) => [... new Array(num).keys()];
// const range = (start,end,step)=>[...function*(){while(start<end)yield start,start+=step}()]
// const range = (start, end) => new Array(end - start).fill(0).map((el, i) => start + i);
// const range = (start, end, step = 1) => new Array(Math.floor((end - start) / step)).fill(0).map((el, i) => start + i * step);

//// geo 参考：https://blog.csdn.net/Richard__Ting/article/details/99319860

export const formatScale = (svgDom, ratio) => {
    return Math.min(svgDom.clientWidth, svgDom.clientHeight) / ratio;
}
export const getCenter = (svgDom) => {
    return [svgDom.clientWidth / 2, svgDom.clientHeight / 2];
}

export const isArray = (obj) => {
    if (Array.isArray) {
        return Array.isArray(obj);
    } else {
        return Object.prototype.toString.call(obj) === '[object Array]';
    }
}

// 获取数据层级
export const getTiers = function (data, k = []) {
    if (isArray(data)) {
        k.push(true);
        if (isArray(data[0])) {
            getTiers(data[0], k);
        }
    }
    return k.length;
}

export const transToGeoData = (data, copyFlag = true) => {
    if (!data) {
        return data;
    }
    if (copyFlag) {
        data = JSON.parse(JSON.stringify(data));
    }
    const dataGeo = [];
    data.forEach(d => {
        if (!d.coordinates) {
            throw 'data error';
        }
        let typeStr = '';
        let tiers = getTiers(d.coordinates);
        if (tiers === 1) {
            typeStr = 'Point'
        } else if (tiers === 2) {
            typeStr = 'LineString'
        } else if (tiers === 3) {
            typeStr = 'Polygon'
        } else {
            throw 'not supported data';
        }
        let dGeo = {
            // 'type': typeStr,
            // 'coordinates': d.coordinates,
            // "properties": d.properties
            "type": "Feature",
            "geometry": {
                'type': typeStr,
                'coordinates': d.coordinates
            },
            "properties": d.properties
        };
        dataGeo.push(dGeo);
    })
    return dataGeo;
}
export const fromSky = (pos, copyFlag = true) => { // inout: 1(outside -> inside), -1(inside -> outside)
    if (copyFlag) {
        pos = Object.assign([], pos);
    }
    if (pos[0] > 180) {
        pos[0] = pos[0] - 360;
    }
    return pos;
}

export const toSky = (pos, copyFlag = true) => {
    if (copyFlag) {
        pos = Object.assign([], pos);
    }
    if (pos[0] < 0) {
        pos[0] = pos[0] + 360;
    }
    return pos;
}

export const toEarthReverse = (pos, copyFlag = true) => {
    if (copyFlag) {
        pos = Object.assign([], pos);
    }
    pos[1] = -pos[1];
    if (pos[0] < 0) {
        pos[0] = pos[0] + 180;
    } else {
        pos[0] = pos[0] - 180;
    }
    return pos;
}

export const toSkyReverse = (pos, copyFlag = true) => {
    if (copyFlag) {
        pos = Object.assign([], pos);
    }
    pos[1] = -pos[1];
    if (pos[0] > 180) {
        pos[0] = pos[0] - 180;
    } else {
        pos[0] = pos[0] + 180;
    }
    return pos;
}

const _transGeoCoordForSky = (coord) => {
    let flag = false;
    if (isArray(coord)) {
        if (isArray(coord[0])) {
            flag = true;
        }
    }
    if (flag) {
        coord.forEach(i => {
            _transGeoCoordForSky(i);
        });
    } else {
        fromSky(coord, false);
    }
}

export const transGeoDataForSky = (geoData, copyFlag = true) => {
    if (!geoData) {
        return geoData;
    }
    let data;
    if (copyFlag) {
        data = Object.assign([], geoData);
    } else {
        data = geoData;
    }
    data.forEach(dt => {
        if (!dt.geometry.coordinates) {
            throw 'data error';
        }
        _transGeoCoordForSky(dt.geometry.coordinates);
    });
    return data;
}

export default {
    formatScale,
    getCenter,
    transToGeoData,
    transGeoDataForSky,
    toEarthReverse,
    toSkyReverse
}